﻿#include "widget.h"
#include "ui_widget.h"
#include <QFileDialog>
#include <QFile>
#include <QDomDocument>
#include <QXmlAttributes>
#include <QDebug>
#include <QMenu>
#include <QAction>
#include <QTreeWidgetItem>
#include <QMessageBox>
#include <QUuid>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonArray>
#include <QJsonValue>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    ui->fileShowTreeWdt->header()->setVisible(false);
    //设置可拖动
//    ui->fileShowTreeWdt->setDragEnabled(true);
//    ui->fileShowTreeWdt->setAcceptDrops(true);
//    ui->fileShowTreeWdt->setDragDropMode(QAbstractItemView::DragDropMode::InternalMove);

    //右键
    ui->fileShowTreeWdt->setContextMenuPolicy(Qt::CustomContextMenu);
    m_pAddNode = new CAddNode();
    connect(m_pAddNode, &CAddNode::sigAddItemInfo, this, &Widget::getAddItemInfo);
    connect(m_pAddNode, &CAddNode::sigAddItemInfo, this, &Widget::addNodeItem);
}

Widget::~Widget()
{
    delete ui;
}

void Widget::showXml(QDomElement &xml)
{
    if(!xml.hasChildNodes())
    {
        //没有内容，只有一个xml根节点
        qWarning() << "no nodes, only root!";
        return;
    }
    else
    {
        //找出root
        QDomElement emt = xml.firstChildElement();
        while(!emt.isNull())
        {
            SItemInfo rootInfo;
            rootInfo.strName = emt.attribute("name");
            rootInfo.strToolTip = emt.attribute("tooltip");
            rootInfo.strColor = emt.attribute("color");
//            qWarning() << "strEmtName" << rootInfo.strName;
            QTreeWidgetItem *pRoot = new QTreeWidgetItem;
            fillItemInfo(pRoot, rootInfo);
            pRoot->setData(0, eColorRole, rootInfo.strColor);
            pRoot->setData(0, eRootRole, "root");
            ui->fileShowTreeWdt->addTopLevelItem(pRoot);

            //找出root下的child节点
            QDomNodeList nodeList = emt.childNodes();
            for(int i = 0; i < nodeList.size(); i++)
            {
                SItemInfo nodeInfo;
                //转换为元素，找到其属性
                nodeInfo.strName = nodeList.at(i).toElement().attribute("name");
                nodeInfo.strToolTip = nodeList.at(i).toElement().attribute("tooltip");
                nodeInfo.strColor = nodeList.at(i).toElement().attribute("color");
//                qWarning() << "strEmtName" << nodeInfo.strToolTip;
                QTreeWidgetItem *pNode = new QTreeWidgetItem(pRoot);
                fillItemInfo(pNode, nodeInfo);
                pNode->setData(0, eColorRole, nodeInfo.strColor);
            }
            emt = emt.nextSiblingElement();
        }
    }
}

void Widget::showJson(QJsonObject &obj)
{
    QJsonObject jsonObject = obj.value("json").toObject();
    QJsonArray rootArray = jsonObject.value("root").toArray();

    for(int i = 0; i< rootArray.size(); i++)
    {
        QJsonObject rootObject = rootArray.at(i).toObject();
        SItemInfo rootItemInfo;
        rootItemInfo.strColor = rootObject.value("color").toString();
        rootItemInfo.strName = rootObject.value("name").toString();
        rootItemInfo.strToolTip = rootObject.value("tooltip").toString();

        QTreeWidgetItem *pRoot = new QTreeWidgetItem;
        fillItemInfo(pRoot, rootItemInfo);
        pRoot->setData(0, eColorRole, rootItemInfo.strColor);
        pRoot->setData(0, eRootRole, "root");
        ui->fileShowTreeWdt->addTopLevelItem(pRoot);

        QJsonArray childArray = rootObject.value("children").toArray() ;
        for(int j = 0; j < childArray.size(); j++)
        {
            QJsonObject childObject = childArray.at(j).toObject();
            SItemInfo childItemInfo;
            childItemInfo.strColor = childObject.value("color").toString();
            childItemInfo.strName = childObject.value("name").toString();
            childItemInfo.strToolTip = childObject.value("tooltip").toString();

            QTreeWidgetItem *pChild = new QTreeWidgetItem(pRoot);
            fillItemInfo(pChild, childItemInfo);
            pChild->setData(0, eColorRole, childItemInfo.strColor);
        }
    }
}

void Widget::fillItemInfo(QTreeWidgetItem *pItem, SItemInfo sItemInfo)
{
    if(!pItem)
    {
        return;
    }
    else
    {
        pItem->setText(0, sItemInfo.strName);
        pItem->setToolTip(0, sItemInfo.strToolTip);
        pItem->setTextColor(0, QColor(sItemInfo.strColor));
    }
}

void Widget::appendXml(QDomDocument &doc, QDomElement &rootEmt, SItemInfo &sItemInfo)
{
    //创建属性
    QDomAttr nameAttr = doc.createAttribute("name");
    QDomAttr tooltipAttr = doc.createAttribute("tooltip");
    QDomAttr colorAttr = doc.createAttribute("color");

    //给属性设置值
    nameAttr.setNodeValue(sItemInfo.strName);
    tooltipAttr.setNodeValue(sItemInfo.strToolTip);
    colorAttr.setNodeValue(sItemInfo.strColor);

    //root节点元素和属性关联
    rootEmt.setAttributeNode(nameAttr);
    rootEmt.setAttributeNode(tooltipAttr);
    rootEmt.setAttributeNode(colorAttr);
}

void Widget::appendJson(QJsonObject &obj, SItemInfo &sItemInfo)
{
    obj["name"] = sItemInfo.strName;
    obj["tooltip"] = sItemInfo.strToolTip;
    obj["color"] = sItemInfo.strColor;
}

void Widget::fillStructInfo(QTreeWidgetItem *pItem, SItemInfo &sItemInfo)
{
    if(pItem)
    {
        sItemInfo.strName = pItem->text(0);
        sItemInfo.strToolTip = pItem->toolTip(0);
        sItemInfo.strColor = pItem->data(0, eColorRole).toString();
    }
}

//暂时打开的文件为已知格式，只存在根节点和一级节点
void Widget::on_openBtn_clicked()
{
    //获取文件路径
    QString strFileName = QFileDialog::getOpenFileName(this, QStringLiteral("打开文件"),
                                                       "", "Files (*.xml *.json)");
    if (strFileName.isEmpty()) {
        return;
    }

    QFile file(strFileName);
    bool isOk = file.open(QIODevice::ReadOnly);

    //判断如果文件打开失败，直接返回，不做操作,成功在接着往下
    if(!isOk)
    {
        qWarning() << "file open error!";
        return;
    }

    QFileInfo fileInfo(strFileName);
    QString strCompleteSuffix = fileInfo.completeSuffix();
    qWarning() << "open strCompleteSuffix" << strCompleteSuffix;
    if(strCompleteSuffix.contains("xml"))
    {
        //file文件要和xml关联起来
        QDomDocument doc;
        isOk = doc.setContent(&file);
        if(!isOk)
        {
            qWarning() << "setContent error!";
            return;
        }
        else
        {
            qWarning() << "open xml...";
            //成功关联的话先获取根节点，已知格式应该是xml节点
            QDomElement root = doc.documentElement();
            ui->fileShowTreeWdt->clear();
            showXml(root);
            ui->fileShowTreeWdt->expandAll();
        }
    }
    else if(fileInfo.completeSuffix().contains("json"))
    {
        //从json文件中读取全部内容
        QString strJson = file.readAll();
        QJsonParseError parseJsonErr;
        QJsonDocument document = QJsonDocument::fromJson(strJson.toUtf8(), &parseJsonErr);
        if(parseJsonErr.error != QJsonParseError::NoError)
        {
            qWarning()<<tr("Analysis json error!");
            return;
        }

        if(!document.isObject())
        {
            return;
        }

        qWarning() << "open json...";
        QJsonObject obj = document.object();
        ui->fileShowTreeWdt->clear();
        showJson(obj);
        ui->fileShowTreeWdt->expandAll();
    }
    else
    {

    }
    file.close();

}

void Widget::on_saveBtn_clicked()
{
    QString strFileName = QFileDialog::getSaveFileName(this, tr("Save File"),
                                                    "./test.xml", tr("xml Files(*.xml);;json Files(*.json)"));
    if (strFileName.isEmpty())
    {
        return;
    }
    QFile file(strFileName); //关联文件名字
    //只写方式打开文件
    bool isOk = file.open(QIODevice::WriteOnly);
    if(!isOk)
    {
        qWarning() << "open file error where create!";
        return;
    }
     //如果打开成功
    QFileInfo fileInfo(strFileName);
    QString strCompleteSuffix = fileInfo.completeSuffix();
    qWarning() << "save strCompleteSuffix" << strCompleteSuffix;
    if(strCompleteSuffix.contains("xml"))
    {
        //创建xml文档对象
        QDomDocument doc;
        //创建xml头部格式 <?xml version='1.0' encoding='utf-8'?>
        QDomProcessingInstruction ins;
        ins = doc.createProcessingInstruction("xml", "version=\'1.0\' encoding=\'utf-8\'");
        //追加元素
        doc.appendChild(ins);

        //根节点元素
        QDomElement root = doc.createElement("xml");
        doc.appendChild(root);

        //写入root和child
        for(int i =0; i < ui->fileShowTreeWdt->topLevelItemCount(); i++)
        {
            SItemInfo sRootItemInfo;
            QTreeWidgetItem *pRootItem = ui->fileShowTreeWdt->topLevelItem(i);
            fillStructInfo(pRootItem, sRootItemInfo);

            //创建root节点元素
            QDomElement rootEmt = doc.createElement("Root");
            appendXml(doc, rootEmt, sRootItemInfo);

            //把root节点追击到根节点后面
            root.appendChild(rootEmt);

            for(int j = 0; j < pRootItem->childCount(); j++)
            {
                SItemInfo sChildItemInfo;
                QTreeWidgetItem *pChildItem = pRootItem->child(j);
                fillStructInfo(pChildItem, sChildItemInfo);

                //创建child节点元素
                QDomElement childEmt = doc.createElement("child");
                appendXml(doc, childEmt, sChildItemInfo);

                //把child节点追击到root节点后面
                rootEmt.appendChild(childEmt);
            }
        }
        QTextStream stream(&file); //文本流关联文件
        doc.save(stream, 4); //4 缩进字符
    }
    else if(fileInfo.completeSuffix().contains("json"))
    {
        QJsonObject obj;
        QJsonObject jsonObject;
        QJsonArray rootArray;

        //写入root和child
        for(int i =0; i < ui->fileShowTreeWdt->topLevelItemCount(); i++)
        {
            SItemInfo sRootItemInfo;
            QTreeWidgetItem *pRootItem = ui->fileShowTreeWdt->topLevelItem(i);
            fillStructInfo(pRootItem, sRootItemInfo);

            QJsonObject rootObject;
            QJsonArray childArray;
            appendJson(rootObject, sRootItemInfo);

            for(int j = 0; j < pRootItem->childCount(); j++)
            {
                SItemInfo sChildItemInfo;
                QTreeWidgetItem *pChildItem = pRootItem->child(j);
                fillStructInfo(pChildItem, sChildItemInfo);

                QJsonObject childObject;
                appendJson(childObject, sChildItemInfo);
                childArray.append(childObject);
            }
            rootObject["children"] = childArray;
            rootArray.append(rootObject);
        }
        jsonObject["root"] = rootArray;
        obj["json"] = jsonObject;

        QJsonDocument document(obj);
        file.write(document.toJson());
    }
    else
    {

    }

    file.close(); //关闭文件

}

void Widget::on_fileShowTreeWdt_customContextMenuRequested(const QPoint &pos)
{
//    qWarning() << "clicked...";
    m_pCurrItem = nullptr;
    QAction* pAddItemAction = new QAction("addItem", ui->fileShowTreeWdt);
    connect(pAddItemAction, &QAction::triggered, [=]
    {
        //获取当前被点击的节点
        QTreeWidgetItem* pCurrItem = ui->fileShowTreeWdt->itemAt(pos);
        if(pCurrItem)
        {
            //点击到Item上,如果不是根节点就不让他添加
            if(pCurrItem->data(0, eRootRole).toString() != "root")
            {
                QMessageBox::information(this, "Hint", "Adding on a non root node is not allowed!",
                                         QMessageBox::Ok);
                return;
            }
            m_pCurrItem = pCurrItem;
        }
        m_pAddNode->exec();
    });
    QMenu *pMenu = new QMenu(ui->fileShowTreeWdt);
    pMenu->addAction(pAddItemAction);
    pMenu->exec(QCursor::pos());

//    //获取当前被点击的节点
//    QTreeWidgetItem* pCurrItem = ui->fileShowTreeWdt->itemAt(pos);
//    if(pCurrItem)
//    {
//        //点击到Item上,如果不是根节点就不让他添加
//        if(pCurrItem->data(0, eRootRole).toString() != "root")
//        {
//            QMessageBox::information(this, "Hint", "Adding on a non root node is not allowed!",
//                                     QMessageBox::Ok);
//            return;
//        }
//        m_pCurrItem = pCurrItem;
//    }

//    connect(pAddItemAction, &QAction::triggered, [=]
//    {
//        m_pAddNode->exec();
//    });
//    m_pAddNode->exec();

}

void Widget::addNodeItem()
{
    QTreeWidgetItem *pAddItem = new QTreeWidgetItem();
    fillItemInfo(pAddItem, m_sItemInfo);
    pAddItem->setData(0, eColorRole, m_sItemInfo.strColor);
//    qWarning() <<"pAddItem.strName" << m_sItemInfo.strName;
    if(!m_pCurrItem)
    {
        //是增加root节点
        pAddItem->setData(0, eRootRole, "root");
        ui->fileShowTreeWdt->addTopLevelItem(pAddItem);
    }
    else
    {
        //增加一级节点
        m_pCurrItem->insertChild(0, pAddItem);
    }
    ui->fileShowTreeWdt->expandAll();
}

void Widget::getAddItemInfo(SItemInfo sItemInfo)
{
    m_sItemInfo = sItemInfo;
}
